﻿using Codice.Client.BaseCommands;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Object = UnityEngine.Object;

namespace Nirvana
{

    public class ReplaceAssetEditor : EditorWindow
    {
        Object targetObj;
        Object replaceObj;

        Vector2 scrollPos = new Vector2(0, 0);
      
        Object selectTargetGameObject;
        Object hightLightTarget;

        string jumpPage = "1";
        int pageNum = 1;
        int row = 15;                   //行

        List<List<Object>> objList = new List<List<Object>>();
 
        [MenuItem("Nirvana/替换资源")]
        public static void OpenTexture()
        {
           

            ReplaceAssetEditor myWindow = (ReplaceAssetEditor)EditorWindow.GetWindow(typeof(ReplaceAssetEditor), false, "查找纹理引用");
            myWindow.Show();
        }


        private void OnGUI()
        {
            GUILayout.Space(10f);

            GUILayout.Label("资源替换说明", GUITheme.LabelTitleStyle);
            EditorGUILayout.HelpBox("多项目混合时，资源Guid冲突，需要重新重建资源，更换资源的Guid引用\n", MessageType.None);
            EditorGUILayout.Space();

            GUILayout.Space(20);

            DrawUI();
            GUILayout.Space(20);
            #region 查找结果
            if (objList != null && objList.Count > 0)
            {
                var maxPage = objList.Count;
                if (pageNum > maxPage)
                {
                    pageNum = maxPage;
                }

                var nowList = objList[pageNum - 1];
                scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

                foreach (var dic in nowList)
                {
                    string str = dic.name;

                    #region 点击对应的标签后触发
                    var editorStyle = EditorStyles.helpBox;
                    if (hightLightTarget != null && hightLightTarget == dic)
                    {
                        editorStyle = EditorStyles.objectFieldThumb;
                        //str = str + "    (当前选择!!!!!)";
                    }
                    if (GUILayout.Button(str, editorStyle, GUILayout.Height(20f)))
                    {

                        selectTargetGameObject = null;
                        hightLightTarget = null;

                        if (selectTargetGameObject == null)
                        {
                            //直接获取资源目录中的prefab
                            selectTargetGameObject = dic;
                        }
                        //根据Object指引对应的位置
                        EditorGUIUtility.PingObject(selectTargetGameObject);
                        Selection.activeObject = selectTargetGameObject;
                        hightLightTarget = dic;
                    }
                    #endregion
                }

                EditorGUILayout.EndScrollView();

                #region 翻页
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("上一页"))
                {
                    if (pageNum <= 1)
                    {
                        pageNum = 1;
                        return;
                    }
                    pageNum--;
                }

                GUIStyle ta_guiStyle = new GUIStyle(GUI.skin.textArea);
                ta_guiStyle.normal.textColor = Color.white;
                ta_guiStyle.alignment = TextAnchor.MiddleCenter;
                ta_guiStyle.fontSize = 15;
                EditorGUILayout.LabelField(pageNum + " / " + maxPage, ta_guiStyle);

                if (GUILayout.Button("下一页"))
                {
                    if (pageNum >= maxPage)
                    {
                        pageNum = maxPage;
                        return;
                    }
                    pageNum++;
                }
                EditorGUILayout.EndHorizontal();

                GUILayout.Space(5);

                EditorGUILayout.BeginHorizontal();
                var t_guiStyle = new GUIStyle(GUI.skin.textArea);
                t_guiStyle.normal.textColor = Color.white;
                t_guiStyle.alignment = TextAnchor.MiddleCenter;
                t_guiStyle.fontSize = 15;
                jumpPage = EditorGUILayout.TextField(jumpPage, t_guiStyle);
                if (GUILayout.Button("跳转"))
                {
                    int jump_num = 1;
                    try
                    {
                        jump_num = int.Parse(jumpPage);

                        if (jump_num < 1 || jump_num > maxPage)
                        {
                            return;
                        }
                        pageNum = jump_num;
                    }
                    catch (Exception)
                    {
                        ShowNotification(new GUIContent("输数字！"));
                    }
                }
                EditorGUILayout.EndHorizontal();
                #endregion

                GUILayout.Space(5);
            }
            #endregion

        }


        private void DrawUI()
        {
            EditorGUILayout.Space();

            targetObj = EditorGUILayout.ObjectField("查找的资源:", targetObj, typeof(Object), true) ;
            GUILayout.Space(20);

            if(replaceObj != null)
            {
                replaceObj = EditorGUILayout.ObjectField("新资源:", replaceObj, typeof(Object), true);
                GUILayout.Space(20);

            }
        

            EditorGUILayout.BeginHorizontal();
            #region 批量查找
            if (GUILayout.Button("1.开始查找引用"))
            {
                //强制刷新当前所有资源
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                if (targetObj == null)
                {
                    this.ShowNotification(new GUIContent("请放入资源!!!!"));
                }
                else
                {
                    pageNum = 1;
                    selectTargetGameObject = null;
                    hightLightTarget = null;
                    objList.Clear();

                    FindAssetDepence();
                    
                }
            }
            #endregion

            if (GUILayout.Button("2.替换新的资源"))
            {
                var targetpath = AssetDatabase.GetAssetPath(targetObj);
               
                var dirpath = Path.GetDirectoryName(targetpath);
                var filename = Path.GetFileNameWithoutExtension(targetpath);
                var fileexp = Path.GetExtension(targetpath);
                var newfilename = string.Concat(filename, "_new",fileexp);
                var newfilepath = Path.Combine(dirpath,newfilename);
                Debug.Log(newfilepath);

                var assetpath = newfilepath.Replace("Assets", "");
                var filepath = string.Concat(Application.dataPath, assetpath);
                if (!File.Exists(filepath))
                {
                    AssetDatabase.CopyAsset(targetpath, newfilepath);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();
                }

                replaceObj = AssetDatabase.LoadAssetAtPath<Object>(newfilepath);
                var replaceGUID = AssetDatabase.AssetPathToGUID(newfilepath);

                string targetGUID = AssetDatabase.AssetPathToGUID(targetpath);
                foreach (var dic in objList)
                {
                    for (int i = 0; i < dic.Count; i++)
                    {
                        var m = dic[i];
                        ReplaceAsset(m, targetGUID, replaceGUID);

                    }
                }

            }

            if (GUILayout.Button("3.删除旧资源"))
            {
                var targetpath = AssetDatabase.GetAssetPath(targetObj);
                targetObj = null;
                AssetDatabase.DeleteAsset(targetpath);
                AssetDatabase.Refresh();
            }
            EditorGUILayout.EndHorizontal();
        }


        void FindAssetDepence()
        {
            var targetpath = AssetDatabase.GetAssetPath(targetObj);

            if (!string.IsNullOrEmpty(targetpath))
            {
                string guid = AssetDatabase.AssetPathToGUID(targetpath);
                Debug.Log("guid: " + guid);
                List<string> withoutExtensions = new List<string>() { ".prefab", ".unity", ".mat", ".asset" };
                string[] files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
                    .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();
                

                int startIndex = 0;
                int maxLength = files.Length;
              

                EditorApplication.update = delegate ()
                {
                    string file = files[startIndex];

                    bool isCancel = EditorUtility.DisplayCancelableProgressBar("匹配资源中", file, (float)startIndex / (float)files.Length);

                    if (Regex.IsMatch(File.ReadAllText(file), guid))
                    {
                        var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(GetRelativeAssetsPath(file));
                        Debug.Log(file, obj);
                        if (obj != null)
                        {
                            if (!CheckHasKey(obj))
                            {
                                AddItem(obj);
                            }
                        }
                    }

                    startIndex++;
                    if (isCancel || startIndex >= files.Length)
                    {
                        EditorUtility.ClearProgressBar();
                        EditorApplication.update = null;
                        startIndex = 0;
                        Debug.Log("匹配结束");
                    }

                };

                //using (ProgressIndicator progress = new ProgressIndicator("generate asset keys", maxLength))
                //{
                //    for (int i = startIndex; i < maxLength; i++)
                //    {
                //        var file = files[i];
                //        progress.SetProgress(i);
                //        progress.ShowForce("check asset:{0}", file);

                //        if (Regex.IsMatch(File.ReadAllText(file), guid))
                //        {
                //            var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(GetRelativeAssetsPath(file));
                //            Debug.Log(file,obj);
                //            if (obj != null)
                //            {
                //                if (!CheckHasKey(obj))
                //                {
                //                    AddItem(obj);
                //                }
                //            }
                //        }
   
                //    }
                //}

            }

            
        }

        void ReplaceAsset(Object obj,string targetGUID,string replaceGUID)
        {

            var objPath = AssetDatabase.GetAssetPath(obj);

            if (!string.IsNullOrEmpty(objPath))
            {
                string guid = AssetDatabase.AssetPathToGUID(objPath);
                var assetpath = AssetDatabase.GUIDToAssetPath(guid);
                assetpath = assetpath.Replace("Assets", "");
                var file = string.Concat(Application.dataPath, assetpath);

                var msg = File.ReadAllText(file);
                msg = msg.Replace(targetGUID, replaceGUID);
                File.WriteAllText(file, msg);

                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }


        }


        private string GetRelativeAssetsPath(string path)
        {
            return "Assets" + Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/');
        }



        bool CheckHasKey(Object key)
        {
            var count = objList.Count;
            for (int i = 0; i < count; i++)
            {
                var dic = objList[i];
                if (dic.Contains(key))
                {
                    return true;
                }
            }
            return false;
        }

        void AddItem(Object mat)
        {
            //分组保存，每组15个
            if (objList.Count <= 0)
            {
                var new_dic = new List<Object>();
                new_dic.Add(mat);
                objList.Add(new_dic);
            }
            else
            {
                var last_dic = objList[objList.Count - 1];
                if (last_dic.Count >= row)
                {
                    var new_dic = new List<Object>();
                    new_dic.Add(mat);
                    objList.Add(new_dic);
                }
                else
                {
                    last_dic.Add(mat);
                }
            }
        }
    }
}
